package priv.yiyuan.example.design.proxy;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

/**
 * 压缩装饰器
 *
 * @author YiYuan
 * @data 2025/9/25
 * @apoNote
 */
public class CompressionDecorator extends FileOperationDecorator {

    public CompressionDecorator(FileOperation decoratedFileOperation) {
        super(decoratedFileOperation);
    }

    private byte[] compress(String data) throws IOException {
        System.out.println("[压缩装饰器] 正在压缩数据...");

        byte[] input = data.getBytes(StandardCharsets.UTF_8);
        Deflater deflater = new Deflater();
        deflater.setInput(input);
        deflater.finish();

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(input.length);
        byte[] buffer = new byte[1024];
        while (!deflater.finished()) {
            int count = deflater.deflate(buffer);
            outputStream.write(buffer, 0, count);
        }

        outputStream.close();
        return outputStream.toByteArray();
    }

    private String decompress(byte[] compressedData) throws IOException, DataFormatException {

        System.out.println("[压缩装饰器] 正在解压缩数据...");
        Inflater inflater = new Inflater();
        inflater.setInput(compressedData);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(compressedData.length);
        byte[] buffer = new byte[1024];
        while (!inflater.finished()) {
            int count = inflater.inflate(buffer);
            outputStream.write(buffer, 0, count);
        }

        outputStream.close();
        return new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
    }

    @Override
    public void write(String filePath, String content) {

        try {
            byte[] compressedContent = this.compress(content);
            String encodedCompressedContent = Base64.getEncoder().encodeToString(compressedContent);
            System.out.println("[压缩装饰器] 写入压缩并编码后的内容。");
            decoratedFileOperation.write(filePath, encodedCompressedContent);
        } catch (IOException e) {
            System.out.println("压缩写入失败: " + e.getMessage());
        }

    }

    @Override
    public String read(String filePath) {

        String encodedCompressedContent = decoratedFileOperation.read(filePath);

        if (encodedCompressedContent != null && !encodedCompressedContent.isEmpty()) {

            try {
                // 将 Base64 字符串解码为字节数组
                byte[] compressedContent = Base64.getDecoder().decode(encodedCompressedContent);
                System.out.println("[压缩装饰器] 读取到压缩内容, 正在解压缩。");
                return this.decompress(compressedContent);

            } catch (IOException | DataFormatException e) {

                System.out.println("解压缩读取失败: " + e.getMessage());

            }

        }

        return "";
    }

}
